IPC trick(Pipe & MessageQueue & SharedMemory)

자세한 code는 SYSTEM PROGRAMMING_IPC 참고
IPC: InterProcess Communication
1. file 사용
2. Message Queue
3. Shared Memory
4. Pipe
5. Signal
6. Semaphore
7. Socket

커널 공간을 이용해서 프로세스간 통신(커널 모드)
- Pipe
    기본 파이프는 단방향 통신
    fork()로 자식 프로세스를 만들었을 때, 부모에서 자식으로의 통신
OS #19 IPC 기법
#include <unistd.h>
char* msg="Hello Child Process!";
int main(){
char buf[255];
int fd[2], pid, nbytes;
if(pipe(fd)<0) // pipe(fd)
exit(1);
pid=fork(); // /
if(pid>0){ // pid ID .
write(fd[1], msg, MSGSIZE); fd[1] msg
exit(0);
}
else{ // pid 0 .
nbytes=read(fd[0], buf, MSGSIZE); // fd[0]
printf("%d %s\n", nbytes, buf);
exit(0);
}
return 0;
}
fork() 시스템콜 호출시 새로운 프로세스 생성-기존 프로세스와 동일하게 생성
원래 프로세스: 부모, 새로운 프로세스: 자식
return 값이 부모프로세스는 기존 프로세스ID, 자식 프로세스는 0으로 들어간다.

pipe()
fd: 크기가 2인 int형 배열을 요구
fd[0]: 함수 호출 후, fd[0]애 데이터를 입력 받을 수 있는 파일 디스크립터가 담김(파이프 출구)
fd[1]: 함수 호출 후 데이터를 출력할 수 있는 파일 디스크립터가 담김(파이프 입구)

pipe(fd) 실행시, fd[0], fd[1]에 각각 파이프 주소를 할당해서 return

write, read 함수를 통해 pipe를 통한 통신

pipe는 커널공간에 존재
- 메세지 큐(message queue)
큐니깐, 기본적으로 FIFO 정책으로 데이터 전송
송신 수신 큐가 보통 각각  2개 생성됨
프로세스 A
msqid=msgget(key, msgflg); // ex) key 1234, msgflg
msgsnd(msqid, &sbuf, buf_length, IPC_NOWAIT);
프로세스 B
msqid=msgget(key, msgflg) // key(1234) msgid .
msgrcv(msqid, &rbuf, MSGSZ, 1, 0);
파이프와 메시지 큐
message queue는 부모/자식이 아니라, 어느 프로세스간에라도 데이터 송수신이 가능
먼저 넣은 데이터가, 먼저 읽어진다.

pipe vs message queue
부모/자식 프로세스간 only or not
단방향/양방향 가능
- 공유 메모리(shared memory)
노골적으로 kernel space에 메모리 공간을 만들고, 해당 공간을 변수처럼 쓰는 방식
message queue 처럼 FIFO 방식이 아니라, 해당 메모리 주소를 마치 변수처럼 접근하는 방식
공유메모리 key를 가지고, 여러 프로세스가 접근 가능
1. 공유 메모리 생성 및 공유 메모리 주소 얻기
shmid=shmget((key_t)1234, SIZE, IPC_CREAT|0666))
shmaddr=shmat(shmid, (void*)0, 0) // .
2. 공유 메모리 쓰기
strcpy((char*)shmaddr, "Linux Programming")
3. 공유 메모리에서 읽기
printf("%s\n", (char*)shmaddr)